package game;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

import entities.Entity;

/**
 * 
 * <p>This class is used internally by the {@link LevelManager} to load a specific level.
 * Currently, only the tags {@code <specuspace>} and {@code <entity>} are supported.</p>
 * 
 * <p>
 * <b>How to use it:</b><br>
 * {@code <specuspace>} is the root element and has to be included.
 * After that, you can add as many {@code <entity>} child entries as you want <br>
 * Each of them can have multiple attributes that will be given to the Entity class for initialization.
 * <p>
 * 
 * <p>Here's an example:<br>
 * <br>
 * {@code <specuspace name="test">}<br>
 * {@code <entity name="entities.TestEntity" spawnx="40" spawny="50" width="20" height="20" />} <br>
 * {@code </specuspace>}
 * </P>
 * 
 * @author Sebastian
 *
 */
public class LevelBuilder {

	public static final String ROOT = "specuspace";
	public static final String NAME = "name";
	public static final String ENTITY = "entity";

	private File levelFile;

	public LevelBuilder(File levelFile) {
		this.levelFile = levelFile;
	}

	/** 
	 * 
	 * Loads the XML file an builds the level.
	 * 
	 * @return the created level with all its entities
	 * @throws JDOMException
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	@SuppressWarnings("unchecked")
	public Level createLevel() throws JDOMException, IOException, ClassNotFoundException {
		HashMap<Class<? extends Entity>, Properties> entityMap;

		SAXBuilder builder = new SAXBuilder();
		Document doc = builder.build(levelFile);

		Element root = doc.getRootElement();
		if (!root.getName().equals(ROOT)) {
			throw new LevelBuildingException("Wrong root element");
		}

		String levelName = "";
		Attribute nameAttr = root.getAttribute(NAME);
		if (nameAttr != null) {
			levelName = nameAttr.getValue();
		}

		entityMap = new HashMap<Class<? extends Entity>, Properties>();
		Class<? extends Entity> entityClass;
		for (Element entityElement : root.getChildren(ENTITY)) {
			String entityName = entityElement.getAttributeValue(NAME);
			if (entityName == null) {
				throw new LevelBuildingException("Entity name ist empty!");
			}
			entityClass = (Class<? extends Entity>) Class.forName(entityName);
			if (entityClass == null) {
				throw new LevelBuildingException("Entity class not found");
			}

			String propertyName;
			String propertyValue;
			Properties props = new Properties();
			for (Attribute propertyAttrbute : entityElement.getAttributes()) {
				propertyName = propertyAttrbute.getName();
				propertyValue = propertyAttrbute.getValue();
				if (propertyValue != null && !propertyValue.isEmpty()) {
					props.put(propertyName, propertyValue);
				}
			}
		}

		return new Level(entityMap, levelName);
	}

	public static void main(String[] args) {
		try {
			LevelBuilder l = new LevelBuilder(new File("res/levels/test.xml"));
			Level test = l.createLevel();
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

}
